package com.web.demo.demo;

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.*;
import net.bytebuddy.matcher.ElementMatchers;

import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import java.util.function.Function;

public class Client {
//    public class UserRepositoryInterceptor {public static String intercept(@Origin Method method, @AllArguments Object[] arguments) {return "小傅哥博客，查询文章数据：https://bugstack.cn/?id=" + arguments[0];}}

    public static void main(String[] args) throws Exception {
        Singable proxy = createByteBuddyDynamicProxy();
        proxy.sing();
        System.out.println(proxy.toString());
    }

    private static Singable createByteBuddyDynamicProxy() throws Exception {
        return (Singable) new ByteBuddy().subclass(Object.class)
                .implement(Singable.class)
                .method(ElementMatchers.named("sing"))
                .intercept(MethodDelegation.to(TestInterceptor.class))
                .make()
                .load(Client.class.getClassLoader())
                .getLoaded()
                .getDeclaredConstructor()
                .newInstance();
    }

    public static class SingerAgentInterceptor {

        private Object delegate;

        public SingerAgentInterceptor(Object delegate) {
            this.delegate = delegate;
        }

        /**
         * @param proxy 代理对象
         * @param method 代理方法
         * @param args 方法参数
         */
        public Object interceptor(@This Object proxy, @Origin Method method,
                                  @AllArguments Object[] args) throws Exception {
            System.out.println("bytebuddy delegate proxy before sing ");
            Object ret = method.invoke(delegate, args);
            System.out.println("bytebuddy delegate proxy after sing ");
            return ret;
        }
    }

    public static class TestInterceptor {
        @RuntimeType
        public static Object intercept(@AllArguments Object[] allArguments, @net.bytebuddy.implementation.bind.annotation.Origin Method method) throws Exception {
            //目标方法执行前执行日志记录
            System.out.println("prepare do method="+method.getName());
            // 调用目标方法
            Object result = "asaa"; //  callable.call();
            //目标方法执行后执行日志记录
            System.out.println("have down method="+method.getName());
            return result;
        }
    }
}
